﻿using System;
using System.Diagnostics;
using System.Reflection;
using Borg.AddOn;

namespace Borg
{
    [Serializable]
    public class ExtensionMethodInvoker : RuntimeElement
    {
        private IMethodInvokerNotificationHook _notificationHook;

        public ExtensionMethodInvoker(Runtime runtime)
            : base(runtime)
        { }

        public void Init(IMethodInvokerNotificationHook notificationHook)
        {
            _notificationHook = notificationHook;
        }

        internal object Invoke(Extension extension, Delegate @delegate, object[] arguments)
        {
            return Invoke(extension, @delegate.Target, @delegate.Method, arguments);
        }

        internal object Invoke(Extension extension, MethodInfo method, object[] arguments)
        {
            Debug.Assert(Runtime.InstanceStore.InternalIsActivated(extension));
            return Invoke(extension, Runtime.InstanceStore.InternalGetExtensionObject(extension), method, arguments);
        }

        internal object Invoke(Extension extension, object target, MethodInfo method, object[] arguments)
        {
            try
            {
                _notificationHook.OnInvocationStarted(extension, method);
                return method.Invoke(target, arguments);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return null;
            }
            finally
            {
                _notificationHook.OnInvocationFinished(extension, method);
            }
        }
    }
}
